import requests
import json
import time
import pymysql
from selenium import webdriver


def get_authorization():
    """
    固定时间获取对应的Authoritarian，避免整个gpt系统失效。
    :return:
    """
    # Authorization是用于验证是不是这个GPT应用的VIP用户

    # 初始化浏览器对象
    browser = webdriver.Edge()
    browser.get("https://ai.xiabb.chat/")


def send_answer(wx: object, msg_after_receive: str, last_msg: str, user: str):
    """
    发送给用户的回复，第一次是表示响应到了他的请求，还有就是将gpt的回答返回给用户。
    :param user: 使用者名称
    :param wx: 窗口组件对象
    :param msg_after_receive: 接收到消息后固定回复使用者的一条消息
    :param last_msg: 最后一条消息
    :return: gpt的回答，当前对话的id
    """
    # 发送第一次回复
    wx.SendKeys(msg_after_receive)
    wx.SendKeys("{Enter}")

    # 调用gpt，发送gpt的回答
    try:
        answer, topic_id = send_to_gpt(user, last_msg)
        wx.SendKeys(answer)
        wx.SendKeys("{Enter}")
        time.sleep(3)
        return answer, topic_id
    except Exception as e:
        answer = "抱歉，遇到错误。"
        return answer, 'wrong'


def save_dialogue(values: tuple):
    '''
    :param values: (联系人，对话角色，对话内容，对话的id)
    :return: 没有返回值
    '''
    # 连接数据库
    conn = pymysql.connect(
        host='localhost',  # 数据库主机地址
        user='root',  # 数据库用户名
        password='123456',  # 数据库密码
        database='wechattalk'  # 数据库名称
    )
    # 创建游标对象
    cursor = conn.cursor()

    # 插入数据
    sql = "INSERT INTO gptmemory (name, role, content, topic_id) VALUES (%s, %s, %s, %s)"
    # values = ('value1', 'value2', 'value3')

    try:
        # 执行 SQL 语句
        cursor.execute(sql, values)

        # 提交事务
        conn.commit()

        print(f"{values}数据插入成功！")

    except Exception as e:
        # 发生错误时回滚事务
        conn.rollback()
        print("数据插入失败:", e)

    finally:
        # 关闭游标和连接
        cursor.close()
        conn.close()


def select_message_from_database(name):
    '''
    :param name: 使用者的名字
    :return: 对应的查询结果
    '''
    # 从数据库中读取当前使用者之前的对话记录
    # 连接数据库
    conn = pymysql.connect(
        host='localhost',  # 数据库主机地址
        user='root',  # 数据库用户名
        password='123456',  # 数据库密码
        database='wechattalk'  # 数据库名称
    )

    # 创建游标对象
    cursor = conn.cursor()

    try:
        # 执行 SQL 查询语句
        sql = f"SELECT * FROM gptmemory WHERE name = '{name}'"
        cursor.execute(sql)

        # 获取查询结果
        results = cursor.fetchall()
        return results

    except Exception as e:
        print("查询失败:", e)

    finally:
        # 关闭游标和连接
        cursor.close()
        conn.close()


def send_to_gpt(user: str, question: str):
    """
    将微信接收的用户消息，有记忆能力的发送请求到GPT，并获得响应返回。
    :param user: 用户的名字
    :param question: 用户提出的问题
    :return: GPT的回答，当前对话的ID
    """
    # 请求头，Authorization是用于验证是不是这个GPT应用的VIP用户
    headers = {
        # 第一行有可能会随着时间的变化而变化
        'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJNZW1iZXJJZCI6MTE4MDM4MjIyNDMwNDY5LCJBY2NvdW50IjoiODU5NzA3MjQzQHFxLmNvbSIsIkFjY291bnRUeXBlIjoxLCJOaWNrTmFtZSI6Ik1fYWNFcXNRYkptdktKIiwiTG9naW5Nb2RlIjoyLCJpYXQiOjE2OTgzNzczMzYsIm5iZiI6MTY5ODM3NzMzNiwiZXhwIjoxNzAwOTY5MzM2LCJpc3MiOiJBSVRvb2xzIiwiYXVkIjoiQUlUb29scyJ9.nEeR_izO2yMakX6ZY9FcwUjMiq9IFwAFXYztBD2kjD4',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Accept': 'application/json, text/plain, */*',
        'Origin': 'https://ai.xiabb.chat',
        'Referer': 'https://ai.xiabb.chat/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61',
        'Accept-Encoding': 'gzip, deflate, br',
        'Content-Type': 'application/json',
        'Sec-Ch-Ua-Platform': '"Windows"',
        'Sec-Fetch-Site': 'same-site',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Ch-Ua-Mobile': '?0',
        'Sec-Ch-Ua': '"Chromium";v="118", "Microsoft Edge";v="118", "Not=A?Brand";v="99"',
    }

    # 获取当前用户的对话记录,组成data中的message格式
    memory = select_message_from_database(user)
    message = []
    for item in memory:
        temp = {
            'content': '',
            'role': ''
        }
        temp['role'] = item[1]
        temp['content'] = item[2]
        message.append(temp)

    # 请求参数，content为你想要问gpt的问题
    data = {
        'topicId': '118773150876933',
        'messages': message,
        'content': question
    }

    # 转成json格式的数据用以发送请求
    json_data = json.dumps(data)
    question = requests.post('https://api.xiabb.chat/chatapi/chat/message', headers=headers, data=json_data)

    # 获得返回的对话id
    id = json.loads(question.text)
    # 发送过去可能是无效字段，返回的值应该自定义为错误。
    try:
        id = id['result'][1]
        answer = requests.post(f'https://api.xiabb.chat/chatapi/chat/message/{id}', headers=headers).text
        return answer, data['topicId']
    except Exception as e:
        answer = '遇到错误，可能是您发送的消息类型gpt无法识别，请重新发送。'

        return answer, data['topicId']
